import { FC, ReactElement, useCallback, useRef } from "react";
import { deletePoker, PokerProps } from "../../../api/pokerAPI";
import {
  DeleteOutlined,
  EditOutlined,
  CaretUpOutlined,
  CaretDownOutlined,
} from "@ant-design/icons";
import { FlexDiv } from "../../BUI";
import { getImagePath } from "../../../constant/url";
import styled from "styled-components";
import { TextEllipsis } from "../../BUI/styled";

interface IProps {
  pokerList: PokerProps[];
  onDeletePoker: (_id: string) => void;
  onUpdatePoker: (poker: PokerProps) => () => void;
}

const PokerList: FC<IProps> = ({
  pokerList,
  onDeletePoker,
  onUpdatePoker,
}): ReactElement => {
  const wrap = useRef<HTMLDivElement | null>(null);

  const handleDeletePoker = useCallback(
    id => async () => {
      const { data } = await deletePoker(id);
      console.log("handleDeletePoker:", data);
      if (data) {
        onDeletePoker(id);
      }
    },
    [onDeletePoker]
  );

  const scrollTo = useCallback(
    // dir:0 向下滚动  1 向上滚动
    (dom, height, dir = 0) =>
      () => {
        const sTop = dom.scrollTop;
        const valid = dir ? sTop > height : sTop < height;
        if (valid) {
          window.requestAnimationFrame(scrollTo(dom, height, dir));
          const diff = Math.abs(sTop - height);
          const dis = diff / 8;
          //差距不足 8 时滚动 4 2 1 0
          const nextScrollDis = dis < 1 ? Math.ceil(diff / 2) : dis;
          let y = sTop - nextScrollDis;
          // 向下滚动
          !dir && (y = sTop + nextScrollDis);
          dom.scrollTo(0, y);
        }
      },
    []
  );

  const onDownScroll = useCallback(() => {
    const { offsetHeight, scrollTop, scrollHeight } =
      wrap.current as HTMLDivElement;
    const maxHeight = scrollHeight - offsetHeight;
    const target = offsetHeight + scrollTop;
    scrollTo(wrap.current, target > maxHeight ? maxHeight : target)();
  }, [scrollTo]);

  const onUpScroll = useCallback(() => {
    const { offsetHeight, scrollTop } = wrap.current as HTMLDivElement;
    const target = scrollTop - offsetHeight;
    scrollTo(wrap.current, target < 0 ? 0 : target, 1)();
  }, [scrollTo]);

  return (
    <Container ref={wrap}>
      <TotalTitle>
        <span data-fill>
          TOTAL: <b>{pokerList.length}</b>
        </span>
        <CaretUpOutlined onClick={onUpScroll} />
        <CaretDownOutlined onClick={onDownScroll} />
      </TotalTitle>
      {pokerList.map((poker: PokerProps) => (
        <ListItem
          key={poker._id}
          poker={poker}
          handleDeletePoker={handleDeletePoker}
          onUpdatePoker={onUpdatePoker}
        />
      ))}
    </Container>
  );
};

export default PokerList;

const TotalTitle = styled.div`
  background: #fff;
  display: flex;
  align-items: center;
  position: sticky;
  position: -webkit-sticky;
  top: 10px;
  z-index: 1;
  scroll-behavior: smooth;
  padding: 5px;
  box-shadow: 1px 2px 10px 0px #cccccccc;
  border-radius: 3px;
  margin: 10px 10px 20px 10px;
  & > span[data-fill] {
    flex: 1;
  }
  & > span[aria-label] {
    cursor: pointer;
    padding: 5px;
    margin-left: 10px;
    border-radius: 3px;
    box-shadow: 4px 4px 8px 0 #cccccccc;
    transition: box-shadow 0.2s linear;

    & > svg {
      transition: transform 0.2s linear;
    }

    &:hover {
      box-shadow: 0 0 3px 0 #cccccccc;
      & > svg {
        transform: scale(1.5);
      }
    }
  }
`;

const Container = styled.div`
  overflow-y: scroll;
  padding-bottom: 100px;
  width: 40%;
`;

const ListItemWrap = styled.div`
  margin: 10px;
  border-radius: 5px;
  box-shadow: 0 0 6px 1px #ddd;
  padding: 5px;
  display: flex;
  flex-direction: column;
  position: relative;

  & > span:first-child {
    font-weight: bold;
    width: calc(100% - 90px);
    ${TextEllipsis};
  }
  & > span:nth-child(2) {
    color: #666;
    font-size: 0.8em;
    width: calc(100% - 90px);
    ${TextEllipsis};
  }
  & > span:nth-child(3) {
    background: #ddd;
    border-radius: 2px;
    padding: 2px 5px;
    margin: 5px 0;
    color: #51f;
  }
  [aria-label] {
    padding: 10px;
    border-radius: 5px;
    box-shadow: 0 0 5px 1px #ccc;
    margin: 5px 10px 0 0;
    transition: box-shadow 0.3s linear;
    &:hover {
      box-shadow: 0 0 15px 5px #ccc;
    }
  }
`;

const PokerImage = styled.img.attrs({ alt: "" })`
  width: 100px;
  height: 100px;
  margin: 0 5px 5px 0;
  border-radius: 3px;
`;

interface ListItemProps {
  poker: PokerProps;
  handleDeletePoker: (id: string) => () => void;
  onUpdatePoker: (poker: PokerProps) => () => void;
}

const ListItem: FC<ListItemProps> = ({
  poker,
  handleDeletePoker,
  onUpdatePoker,
}) => (
  <ListItemWrap>
    <span>{poker.title}</span>
    <span>{poker.description}</span>
    <span>{poker.url}</span>

    <FlexDiv>
      {poker.images.map((file: any, index: any) => (
        <PokerImage src={getImagePath + file} key={index} />
      ))}
    </FlexDiv>
    <FlexDiv style={{ position: "absolute", right: 0, top: 0 }}>
      <DeleteOutlined onClick={handleDeletePoker(poker._id)} />
      <EditOutlined onClick={onUpdatePoker(poker)} />
    </FlexDiv>
  </ListItemWrap>
);
